package com.mgq.juc.cas;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
 * java针对累加操作,提供了原子累加器,性能比atomicInter的速度更快
 * 原理是:针对一个变量进行CAS时,竞争会非常激烈, 累加器的思想是构造多个cell,分别做累加 线程1累加cell[0],线程2累加cell[1]
 * 最终将所有的累加操作进行组合即可
 */
public class TestAdder {
    public static void main(String[] args) {
        for (int i = 0; i < 4; i++) {
            demo(
                    ()->new AtomicLong(0),
                    AtomicLong::getAndIncrement
            );
        }

        System.out.println("------------------------------");
        for (int i = 0; i < 4; i++) {
            demo(LongAdder::new,LongAdder::increment);
        }


    }


    public static <T> void demo(Supplier<T> supplier, Consumer<T> consumer) {
        T adder = supplier.get();
        long start = System.nanoTime();
        List<Thread> list = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            Thread thread = new Thread(() -> {
                for (int j = 0; j < 500000; j++) {
                    consumer.accept(adder);
                }
            });
            list.add(thread);
        }
        list.forEach(Thread::start);
        list.forEach(thread -> {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        long end = System.nanoTime();
        //1000_000 是java7的语法糖,可以使用下划线,方便阅读数字
        System.out.println("累加结果"+adder+",累计花费时间为:"+ (end - start)/1000_000);
    }
}


